/* eslint-disable */
/*
[1] CSS样式不允许出现空样式；
[2] 类名不能出现驼峰规则；
[3] a标签中不允许使用div；
[4] a标签中不允许使用p标签；
[5] li的同级元素不能是div；
*/
const createHtmlDom = require('htmldom')
const CssDom = require('cssdom')
const fs = require('fs')

module.exports = {
  errors: [],
  unusedCss: [],
  print(color, msg) {
    let map = {
      bright: '\x1B[1m', // 亮色
      grey: '\x1B[2m', // 灰色
      italic: '\x1B[3m', // 斜体
      underline: '\x1B[4m', // 下划线
      reverse: '\x1B[7m', // 反向
      hidden: '\x1B[8m', // 隐藏
      black: '\x1B[30m', // 黑色
      red: '\x1B[31m', // 红色
      green: '\x1B[32m', // 绿色
      yellow: '\x1B[33m', // 黄色
      blue: '\x1B[34m', // 蓝色
      magenta: '\x1B[35m', // 品红
      cyan: '\x1B[36m', // 青色
      white: '\x1B[37m', // 白色
      blackBG: '\x1B[40m', // 背景色为黑色
      redBG: '\x1B[41m', // 背景色为红色
      greenBG: '\x1B[42m', // 背景色为绿色
      yellowBG: '\x1B[43m', // 背景色为黄色
      blueBG: '\x1B[44m', // 背景色为蓝色
      magentaBG: '\x1B[45m', // 背景色为品红
      cyanBG: '\x1B[46m', // 背景色为青色
      whiteBG: '\x1B[47m' // 背景色为白色
    }
    console.log(map[color] || map['bright'], msg, '\x1b[0m')
  },
  filePath() {
    return process.argv[2]
  },
  judgeClassExistInTag(htmlContent, selectors) {
    if (selectors.includes('>') || selectors.includes(':') || selectors.includes('[')) return true
    let sels = selectors.split(' ')
    sels = sels.map(item => item.replace(/\./g, '').replace(/#/g, ''))
    return sels.every(item => htmlContent.includes(item))
  },
  validate() {
    let p = this.filePath()
    let filePath = p.split('=')[1]
    let vueContent = fs.readFileSync(filePath).toString()
    let $ = createHtmlDom(vueContent)
    // 1. 环境校验
    this.checkFileValidate(filePath, $)
    // 2. HTML标签校验
    this.checkHtml(filePath, $)
    // 3. 样式校验
    this.checkCss(filePath, $)
    let errors = this.errors
    if (errors.length) {
      errors = errors.map((item, index) => {
        return `【${index + 1}】${item}`
      })
      console.log('\n' + filePath + '\n')
      this.print('red', errors.join('  \n'))
      process.exit(1)
    } else {
      this.print('green', `The path named "${filePath}" be validated successfully.`)
      process.exit(0)
    }
  },
  // 必须存在template标签，style为scss、less类型不校验
  checkFileValidate(filePath, $) {
    let styleEl = $('style')[0]
    if (!styleEl) {
      this.print('red', `The path named "${filePath}" 文件中无style标签.`)
      process.exit(1)
    }
    if (styleEl.attributes && styleEl.attributes.lang && ['scss', 'less'].includes(styleEl.attributes.lang)) {
      process.exit(0)
    }
  },
  // CSS检查
  checkCss(filePath, $) {
    const _this = this
    var css = new CssDom($('style')[0].textContent)
    var templateEl = $('template')
    // 无template标签时，不校验
    if (!templateEl || !templateEl.html()) {
      return
    }
    css.dom.forEach((item, index) => {
      let { type, selectors, declarations } = item
      if (type !== 'rule') return
      // 当个css样式中存在“css-ignore” 则忽略校验
      if (declarations && JSON.stringify(declarations).includes('css-ignore')) return
      if (!Object.keys(declarations).length) {
        // [1] CSS样式不允许出现空样式
        _this.errors.push(`“${selectors.join(' | ')}”为空样式，请删除！`)
        return
      }
      // 遍历CSS选择器
      selectors.forEach(sel => {
        // 检测官网样式不能以 /deep/ ::deep  ::v-deep 开头的样式
        if(sel.startsWith('>>>') || sel.startsWith('::v-deep') || sel.startsWith('/deep/')){
          _this.errors.push(`“${sel}”类名命名不规范，不支持样式开头直接是【>>>】【/deep/】【::v-deep】，请使用父级classname包裹！`)
        }else{
          // 如果是中间包含这些 关键字  就不需要校验了
          if (sel.includes('>>>') || sel.includes('/deep/') || sel.includes('::v-deep')) return
        }


        let currentSelector = sel.replace(/\s*[>]{3}\s*/g, ' ').replace(/\s*\/deep\/\s*/g, '')
        // htmldom不支持伪类查找
        if (currentSelector.includes(':')) return
        let currentSelectorArr = currentSelector.split(/\s+/)
        let isNonStandard = currentSelectorArr.some(item => {
          return item.startsWith('.') && /[A-Z]/.test(item)
        })
        // [2] 类名不能出现驼峰规则
        if (isNonStandard) {
          _this.errors.push(`“${sel}”类名命名不规范，不支持驼峰规则，请删除！`)
        }
        // let findEl = templateEl.find(currentSelector)
        // if (
        //   !currentSelector.includes('el-') &&
        //   !_this.judgeClassExistInTag(templateEl.html(), currentSelector) &&
        //   findEl &&
        //   !findEl.__length__
        // ) {
        //   _this.unusedCss.push(sel)
        // }
      })
    })

    // if (_this.unusedCss.length) {
    //   // [3] 定义了的样式未被使用（2023年12月4日去除该校验）
    //   _this.errors.push(`“${_this.unusedCss.join('\n')}”定义了但未被使用，请删除！`)
    // }
  },
  // 检测HTML标签
  checkHtml(filePath, $) {
    const _this = this
    var templateEl = $('template')
    // 无template标签时，不校验
    if (!templateEl || !templateEl.html()) {
      return
    }
    // [1] a标签中不允许使用div标签
    let isExistAIncludesDiv = templateEl.find('a div')
    if (isExistAIncludesDiv.__length__) {
      _this.errors.push(`代码中存在a标签包含div的情形，请修改！`)
    }
    // [2] a标签中不允许使用p标签
    let isExistAIncludesP = templateEl.find('a p')
    if (isExistAIncludesP.__length__) {
      _this.errors.push(`代码中存在a标签包含p标签的情形，请修改！`)
    }
    // [3] li的同级元素不能是div
    let isExistUlIncludesDiv = templateEl.find('ul>div')
    if (isExistUlIncludesDiv.__length__) {
      _this.errors.push(`代码中存在ul子级为div标签的情形，请修改！`)
    }
  }
}
